#include "network.h"
#include "database.h"
#include <QVector>
#include <QDebug>
Network::Network(QObject *parent) : QObject(parent)
{
    //1、连接数据库
    db = new Database();
    //2、获取配置信息
    QVector<ConfigInfo*> v = db->getConfigInfoInfo();

    // 日志
    this->sw = new ShowWidget;
    for(auto item : v)
    {
        //根据端口号初始化串口信息
        initSerialPort(item->getPortNo());
        if(item->getProtocol()==1)
        {
            //创建TCPServer连接
            createTCPServer(item);
            this->sw->writeFile("开始创建TCP Server连接！");
        }
        else if(item->getProtocol()==2)
        {
            //创建TCPClient连接
            createTcpClient(item);
            this->sw->writeFile("开始创建TCP Client连接！");
        }
        else if(item->getProtocol()==3)
        {
            //创建UDP连接
            createUdp(item);
            this->sw->writeFile("开始创建 UDP 连接！");
        }

    }

}

void Network::initSerialPort(int portno)
{
     portinfo = db->getPortInfoByPortNo(portno); //获取串口信息
     if(!portinfo)
     {
         qDebug()<<"串口信息为空";
         this->sw->writeFile("串口信息为空");
         return;
     }
     setSerialPort(portinfo); //配置串口信息
}

void Network::setSerialPort(PortInfo* portinfo)
{
    QSerialPort* serialport = new QSerialPort(this);
    serialport->setPortName(portinfo->getComNm()); //配置串口名
    serialport->setBaudRate(portinfo->getBaudRate()); //波特率
    if(portinfo->getDataBit()==8)
    {
        serialport->setDataBits(QSerialPort::Data8);  //数据位
    }
    if(portinfo->getCheckBit()==1)
    {
        serialport->setParity(QSerialPort::NoParity);   //校验位
    }

    if(portinfo->getStopBit()==1)
    {
        serialport->setStopBits(QSerialPort::OneStop); //停止位
    }
    serialport->setFlowControl(QSerialPort::NoFlowControl);
    map[portinfo->getPortNo()] = serialport;
}

void Network::createTCPServer(ConfigInfo *configinfo)
{
    this->tcpserver = new QTcpServer(this);
    int portno = configinfo->getPortNo();
    if(!this->tcpserver->listen(QHostAddress::Any,portno))
    {
        qDebug()<<"端口连接失败";
        this->sw->writeFile("tcpserver端口连接失败！");
        return ;
    }

    // 设置最大连接数
    this->tcpserver->setMaxPendingConnections(configinfo->getLinksNum());

    QSerialPort* serialport = map[portno];
    // 打开串口
    if (!serialport->open(QIODevice::ReadWrite))
    {
        qDebug() << "串口打开失败：" << serialport->errorString();
        this->sw->writeFile("串口打开失败！");
        return;
    }

    connect(this->tcpserver,&QTcpServer::newConnection,[=](){
        //获取socker对象
        this->tcpsocker = this->tcpserver->nextPendingConnection();

        //接受数据
        connect(this->tcpsocker,&QTcpSocket::readyRead,[=](){
            QByteArray buf = this->tcpsocker->readAll();
            qDebug()<<"获取到的数据"<<buf;
            this->sw->writeFile(QString("获取得到的数据：%1").arg(QString(buf)));
            //写到串口中
            connect(serialport,&QSerialPort::readyRead,[=](){
                writeClient(serialport);
            });
            writeSerialport(buf,serialport);
        });
    });
}

void Network::createTcpClient(ConfigInfo *configinfo)
{
    this->tcpsocker = new QTcpSocket(this);
    int portno = configinfo->getPortNo();
    QSerialPort* serialport = map[portno];
    // 打开串口
    if (!serialport->open(QIODevice::ReadWrite))
    {
        qDebug() << "串口打开失败：" << serialport->errorString();
        this->sw->writeFile(QString("TCP Client 串口打开失败 %1").arg(serialport->errorString()));
        return;
    }


    QString ip = configinfo->getPeerHost();
    int port  = configinfo->getPeerPort();
    qDebug() << "ip :" << ip <<" " <<"port: "<<port;
    this->sw->writeFile(QString("TCP Client的IP:%1  Port:%2").arg(ip).arg(port));
    this->tcpsocker->connectToHost(ip,port);
    connect(this->tcpsocker,&QTcpSocket::connected,[=](){
        qDebug() << "创建和服务器的连接";
        this->sw->writeFile("创建了和服务器的连接");
    });
    connect(this->tcpsocker,&QTcpSocket::readyRead,[=](){
        QByteArray buf = this->tcpsocker->readAll();
        qDebug() << "往串口中写的数据："<<buf;
        this->sw->writeFile(QString("向串口里写数据：%1").arg(QString(buf)));
        //写到串口中
        connect(serialport,&QSerialPort::readyRead,[=](){
            writeClient(serialport);
        });
        writeSerialport(buf,serialport);
    });
}

void Network::writeSerialport(QByteArray buf, QSerialPort *serialport)
{
    quint8 result = serialport->write(buf);
    if(result == -1)
    {
        qDebug()<<"往串口中写入失败";
        this->sw->writeFile("向串口里写入数据失败！");
        return;
    }
}

void Network::writeClient(QSerialPort *serialport)
{
    QByteArray buf =  serialport->readAll();
    qDebug()<<"串口中读取到的数据：" << buf;
    this->sw->writeFile(QString("串口中读取到的数据 %1").arg(QString(buf)));
    if(buf.isEmpty())
    {
        qDebug()<<"未读取到数据";
        this->sw->writeFile("没有读取到数据");
        return;
    }
    this->tcpsocker->write(buf); //往客户端写数据
    buf = " "; //清空操作
}

void Network::createUdp(ConfigInfo *configinfo)
{
    this->udpsocker = new QUdpSocket(this);
    int portno = configinfo->getPortNo();

    if (!this->udpsocker->bind(portno)) {
        qDebug() << "绑定失败：" << this->udpsocker->errorString();
        this->sw->writeFile(QString("UDP 绑定失败 %1").arg(this->udpsocker->errorString()));
    } else {
        qDebug() << "绑定成功，端口：" << portno;
        this->sw->writeFile(QString("UDP 绑定成功，端口为：%1").arg(portno));
    }

    QSerialPort* serialport =  map[portno];
    // 打开串口
    if (!serialport->open(QIODevice::ReadWrite))
    {
        qDebug() << "串口打开失败：" << serialport->errorString();
        this->sw->writeFile(QString("UDP 串口打开失败：%1").arg(serialport->errorString()));
        return;
    }

    connect(this->udpsocker,&QUdpSocket::readyRead,[=](){
          qDebug() << "收到 UDP 数据！";
        qDebug() << "-----udp";
        char c[1024] = {};

        QHostAddress ip; //接收ip
        quint16 port; //接收port
        this->udpsocker->readDatagram(c, 1024, &ip, &port);
        qDebug() << c;
        //往串口中写数据
        serialport->write(c);
        connect(serialport,&QSerialPort::readyRead,[=](){
            //往客户端写数据
            QByteArray buf = serialport->readAll();
            qDebug()<<"串口中读取到的数据：" << buf;
            this->sw->writeFile(QString("串口读取的数据：%1").arg(QString(buf)));
            if(buf.isEmpty())
            {
                qDebug()<<"未读取到数据";
                this->sw->writeFile("未读取到数据");
                return;
            }
              //往客户端写数据
             this->udpsocker->writeDatagram(buf, QHostAddress(ip), port);

            buf = " "; //清空操作
        });
    });
}

